#include "read_boy_confg.h"
#include "readboy_epd_2_9_a01.h"
#include "read_boy.h"

//dev290A(){ epdWidth=128; epdHeight=296; idleSlowRf=1800; idleFastRf=550; }
#if defined(READ_BOY_DEV_2_9_A01) 
const   unsigned char lut_slow[] =
{
  /*  0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, 
    0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88, 
    0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51, 
    0x35, 0x51, 0x51, 0x19, 0x01, 0x00*/
  0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const   unsigned char lut_fast[] =
{
    0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, //0x13,0x14,0x44,0x12
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const   unsigned char lut_grey_update[]={ //从上到下是依次加深
  0x10, 0x00, 0x10, 0x00, 0x10, 0x01, 0x10, 0x01,
  0x10, 0x02, 0x10, 0x02, 0x10, 0x03, 0x10, 0x04,
  0x10, 0x14, 0x10, 0x24, 0x10, 0x34, 0x11, 0x44,
  0x12, 0x44, 0x13, 0x44
};



drv_Base_t my_drv_base;

void my_drv_base_init(){
    my_drv_base.iLut = 15;
    my_drv_base.sleeping = 1;
    my_drv_base.epdWidth = FB_WIDTH;
    my_drv_base.epdHeight = FB_HEIGHT;
    my_drv_base.idleFastRf = 350;
    my_drv_base.idleSlowRf = 1300;
    
    my_drv_base.in_trans = 0;
    my_drv_base._quality = 3; //灰度显示品质 默认2 0,2-高品质 1,3-低品质高兼容性. 0,1使用bayer灰度二值表 2,3使用floyd算法   
    my_drv_base.lastRefresh = 0;
    
    my_drv_base.drv_fullpart = &read_boy_2_9_a01_drvBase_drv_fullpart;
    my_drv_base.drv_setDepth = &read_boy_2_9_a01_drvBase_drv_setDepth;
    my_drv_base.drv_sleep = &read_boy_2_9_a01_drvBase_drv_sleep;
//    my_drv_base.lut_Init = &read_boy_drvBase_Init;
    my_drv_base.drv_dispWriter = &read_boy_2_9_a01_drvBase_drv_dispWriter;
}



int read_boy_2_9_a01_drvBase_Init(const unsigned char* lut) {
  // * EPD hardware init start /
  //this->lut = lut;
    my_drv_base.lut = lut;
  if(my_drv_base.sleeping) {
    //Reset();
    readboyEpdBase_Reset(200);  
    my_drv_base.sleeping=0;
  }
  //BeginTransfer();
  readboyEpdBase_BeginTransfer();
  readboyEpdBase_boy_epdCmd(0x01);
  readboyEpdBase_boy_epdParam((my_drv_base.epdHeight - 1) & 0xFF);
  readboyEpdBase_boy_epdParam(((my_drv_base.epdHeight - 1) >> 8) & 0xFF);
  readboyEpdBase_boy_epdParam(0x00);                     // GD = 0; SM = 0; TB = 0;
  readboyEpdBase_boy_epdCmd(0x0c);
  readboyEpdBase_boy_epdParam(0xD7);
  readboyEpdBase_boy_epdParam(0xD6);
  readboyEpdBase_boy_epdParam(0x9D);
  readboyEpdBase_boy_epdCmd(0x2c);
  readboyEpdBase_boy_epdParam(0x9B);                     // VCOM 7C
  readboyEpdBase_boy_epdCmd(0x3a);
  readboyEpdBase_boy_epdParam(0x1A);                     // 4 dummy lines per gate
  readboyEpdBase_boy_epdCmd(0x3b);
  readboyEpdBase_boy_epdParam((my_drv_base.iLut==1)?0x02:((my_drv_base.iLut==3 || my_drv_base.iLut==5)?0x05:0x08)); // 2us per line
  readboyEpdBase_boy_epdCmd(0x11);
  readboyEpdBase_boy_epdParam(0x03);                     // X increment; Y increment
  readboyEpdBase_boy_epdCmd(0x32);
  for (int i = 0; i < 30; i++) {
    if(my_drv_base.iLut>0 && my_drv_base.iLut<15 && i>19 && i<23){
      //readboyEpdBase_boy_epdParam(pgm_read_byte(lut_grey_update+iLut*2+i-(i==20?22:23)));
        readboyEpdBase_boy_epdParam(lut_grey_update[0+my_drv_base.iLut*2+i-(i==20?22:23)]);
    }
    else
      //readboyEpdBase_boy_epdParam(pgm_read_byte(this->lut+i));
        readboyEpdBase_boy_epdParam(my_drv_base.lut[0+i]);
  }
  readboyEpdBase_EndTransfer();
  return 0;
}

void read_boy_2_9_a01_drvBase_drv_fullpart(bool part){ //切换慢刷/快刷功能
  if(my_drv_base.lastRefresh) return;
  if(!part) my_drv_base.iLut=15;
  if(my_drv_base.sleeping) my_drv_base.iLut=15;
  else read_boy_2_9_a01_drvBase_Init(part?lut_fast:lut_slow);
}


//void read_boy_drvBase_drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新等功能

void read_boy_2_9_a01_drvBase_drv_dispWriter(read_boy_drv_dispWriter_t *f,uint8_t m){ //单色刷新等功能    
  if(m&1){//stage 1
      if(my_drv_base.lastRefresh){ 
          read_boy_2_9_a01_drvBase_drv_dispWriter(f,2);
      }
      if(my_drv_base.sleeping){ 
          read_boy_2_9_a01_drvBase_Init(lut_slow);
      }
      readboyEpdBase_BeginTransfer();
      readboyEpdBase_SetMemory();   // bit set = white, bit reset = black
      readboyEpdBase_boy_epdBusy(100);
      readboyEpdBase_boy_epdCmd(0x24);  /* will send the color data */
      for (int i = 0; i < my_drv_base.epdHeight*my_drv_base.epdWidth / 8; i++) {
          SpiTransfer(f(i));
      }
      readboyEpdBase_boy_epdCmd(0x22);
      readboyEpdBase_boy_epdParam(0xC4);
      readboyEpdBase_boy_epdCmd(0x20);
      readboyEpdBase_boy_epdCmd(0xff);
      readboyEpdBase_EndTransfer();
      //my_readboyEpdBase.lastRefresh=millis();
      my_drv_base.lastRefresh=1000;//================================================
  }

  if(m&2){//stage 2
    uint32_t ms=1000-my_drv_base.lastRefresh;//====================================================
    uint32_t u=(my_drv_base.lut == (const uint8_t*)lut_fast)?my_drv_base.idleFastRf:my_drv_base.idleSlowRf;
    if(ms<u) {
        readboyEpdBase_boy_epdBusy(u-ms);
        //readboyEpdBase_boy_epdBusy(1300);//=============================
    }
    //readboyEpdBase_boy_epdBusy(1000);//=============================
    my_drv_base.lastRefresh=0;
    readboyEpdBase_BeginTransfer();
    readboyEpdBase_SetMemory();   // bit set = white, bit reset = black
    readboyEpdBase_boy_epdBusy(90);
    readboyEpdBase_boy_epdCmd(0x26);  /* will send the color data */
    for (int i = 0; i < my_drv_base.epdHeight*my_drv_base.epdWidth / 8; i++) {
        SpiTransfer(f(i));
    }
    readboyEpdBase_EndTransfer();
  }
}

void read_boy_2_9_a01_drvBase_drv_sleep() { //开始屏幕睡眠
  //if(RST_PIN>=0) { //未定义RST_PIN时无法唤醒
    readboyEpdBase_BeginTransfer();
    readboyEpdBase_boy_epdCmd(0x10);
    readboyEpdBase_EndTransfer();
    readboyEpdBase_boy_epdBusy(150);
    DigitalWrite(EPD_RST_PIN, LOW);
  //}
  my_drv_base.sleeping=1;
}

void read_boy_2_9_a01_drvBase_drv_setDepth(uint8_t i){
  my_drv_base.iLut = i?(i>15?15:i):15;
  read_boy_2_9_a01_drvBase_Init(lut_fast);
}


#endif









































